# -*- coding:utf8 -*-
import copy
import math
import typing
import json
import traceback
from scrapy import Request, FormRequest
from squirrel_core.frame.spider_makaka import MakakaSpider
from squirrel_core.item.procedure_item import ProcedureItem
from squirrel_spiders.shuzixindong.password_encrypt import *


class shuzixindong_score(MakakaSpider):
    name = "shuzixindong_score"
    login_url = "https://api-changzheng.chinaath.com/changzheng-user-center-api/login"
    unbind_url = "https://api-changzheng.chinaath.com/changzheng-user-center-api/api/authentication/business/unBusinessAuthentication"
    bind_url = "https://api-changzheng.chinaath.com/changzheng-user-center-api/api/authentication/business"
    user_url = "https://api-changzheng.chinaath.com/changzheng-user-center-api/api/account/app/detail/get"
    score_url = "https://api-changzheng.chinaath.com/changzheng-common-proxy-api/api/score/proxy/queryMineOfflineRaceScore"
    header = {
        "machineCode": "6bd839d8b9f7f76d",
        "osId": "1002",
        "device": "pad/12 HUAWEI MGA-AL00",
        "versionNumber": "519",
        "versionCode": "5.54.0",
        "terminalType": "1",
        "Content-Type": "application/x-www-form-urlencoded",
        "Host": "api-changzheng.chinaath.com",
    }

    def get_ext_requests_or_urls(self, data=None):
        try:
            if data and isinstance(data, str):
                data = json.loads(data)
            if data and isinstance(data, typing.MutableMapping):
                self.logger.info("开始登录")
                phone = data.get("phone", "13981808836")
                pwd = data.get("password", "aa123456")
                card_num = data.get("card_num", "511024198803060014")
                user_name = data.get("user_name", "陈相林")
                password = encrypt_password(pwd)
                login_data = {"loginType": "0", "password": password, "phone": phone, "encryptType": "1"}
                yield FormRequest(url=self.login_url, formdata=login_data, callback=self.parse,
                                  headers=self.header, dont_filter=True, errback=self.err_parse,
                                  cb_kwargs={"card_num": card_num, "user_name": user_name})
        except Exception:
            self.logger.error(f"登录时出错：{traceback.format_exc()}")

    def parse(self, response, **kwargs):
        item = ProcedureItem()
        try:
            self.logger.info("开始判断用户是否已实名")
            data = json.loads(response.text)
            msg = data.get("msg", "")
            if data.get("success", True) or msg == "success":
                item["_result"] = {
                    "note": "任务启动成功",
                    "code": 200,
                    "success": True
                }
                yield item

                token = data.get("data", {}).get("token", "")
                card_number = data.get("data", {}).get("userInfo", {}).get("cardNumber", "")
                header = copy.deepcopy(self.header)
                header.update({"token": token, "Content-Type": "application/json; charset=UTF-8"})
                if card_number:
                    #可查询成绩的赛事
                    # data = {"raceCategoryCodeList": ["race_type_offline"], "searchType": "1", "pageNo": "1", "pageSize": "1000",
                    #         "keyword": ""}
                    # yield Request(url=self.all_race_url, callback=self.all_race_parse, method="POST", headers=header,
                    #               body=json.dumps(data), dont_filter=True, meta={"header": header})


                    yield Request(url=self.unbind_url, callback=self.unbind_parse, method="POST", headers=header,
                                  cb_kwargs=kwargs, errback=self.err_parse,
                                  body=json.dumps({"cardNumber": card_number}), dont_filter=True, meta={"header": header})
                else:
                    # bind_data = {"authType": 1,
                    #              "realNameAuthenticationInfo": {"cardNumber": "511321198612302823", "cardType": 0,
                    #                                             "userName": "杜璐"}}
                    card_num = kwargs.get("card_num", "")
                    user_name = kwargs.get("user_name", "")
                    bind_data = {"authType": 1,
                                 "realNameAuthenticationInfo": {"cardNumber": card_num, "cardType": 0,
                                                                "userName": user_name}}
                    yield Request(url=self.bind_url, callback=self.bind_parse, method="POST", headers=header,
                                  cb_kwargs=kwargs, errback=self.err_parse,
                                  body=json.dumps(bind_data), dont_filter=True, meta={"header": header})
            elif "手机号错误" in msg:
                item["_result"] = {
                    "note": "手机号错误",
                    "code": 201,
                    "success": False
                }
                yield item
            elif "密码错误" in msg:
                item["_result"] = {
                    "note": "登录密码错误",
                    "code": 202,
                    "success": False
                }
                yield item
            else:
                item["_result"] = {
                    "note": "登录异常",
                    "code": 203,
                    "success": False
                }
                yield item
        except Exception:
            self.logger.error(f"判断是否实名时出错：{traceback.format_exc()}")
            item['_result'] = {
                'note': 'password has been locked',
                'code': 220,
                'success': False
            }
            yield item

    def unbind_parse(self, response, **kwargs):
        try:
            self.logger.info("解绑登录用户")
            stop_flag = kwargs.get("stop_flag", False)
            if not stop_flag:
                data = json.loads(response.text)
                new_token = data.get("data", {}).get("newToken", "")
                # bind_data = {"authType": 1,
                #              "realNameAuthenticationInfo": {"cardNumber": "511321198612302823", "cardType": 0,
                #                                             "userName": "杜璐"}}
                card_num = kwargs.get("card_num", "")
                user_name = kwargs.get("user_name", "")
                bind_data = {"authType": 1,
                             "realNameAuthenticationInfo": {"cardNumber": card_num, "cardType": 0,
                                                            "userName": user_name}}
                header = response.meta.get("header", {})
                header.update({"token": new_token})
                yield Request(url=self.bind_url, callback=self.bind_parse, method="POST", headers=header, errback=self.err_parse,
                              body=json.dumps(bind_data), dont_filter=True, cb_kwargs=kwargs, meta={"header": header})
        except Exception:
            self.logger.error(f"解绑登录用户时出错：{traceback.format_exc()}")

    def bind_parse(self, response, **kwargs):
        try:
            self.logger.info("开始绑定查询用户")
            data = json.loads(response.text)
            new_token = data.get("data", {}).get("newToken", "")
            header = response.meta.get("header", {})
            header.update({"token": new_token})
            header.pop("Content-Type")
            yield Request(url=self.user_url, callback=self.user_parse, headers=header, dont_filter=True,
                          errback=self.err_parse, cb_kwargs=kwargs, meta={"header": header})
        except Exception:
            self.logger.error(f"绑定查询用户时出错：{traceback.format_exc()}")

    def user_parse(self, response, **kwargs):
        try:
            self.logger.info("解析用户信息")
            data = json.loads(response.text).get("data", "")
            new_card_number = data.get("userInfo", {}).get("cardNumber", "")
            kwargs.update({"new_card_number": new_card_number})

            header = response.meta.get("header", {})
            header.update({"Content-Type": "application/json; charset=UTF-8"})
            score_data = {"offlineScoreType": 2, "pageNo": 1, "pageSize": 100}
            yield Request(url=self.score_url, callback=self.score_parse, method="POST", headers=header, errback=self.err_parse,
                          body=json.dumps(score_data), dont_filter=True, cb_kwargs=kwargs, meta={"header": header})
        except Exception:
            self.logger.error(f"解析用户信息时出错：{traceback.format_exc()}")

    def score_parse(self, response, **kwargs):
        try:
            self.logger.info("开始解析成绩信息")
            header = response.meta.get("header", {})
            score_page_flag = response.meta.get("score_page_flag", False)
            data = json.loads(response.text).get("data", {})
            score_list = response.meta.get("score_list", [])
            score_list.extend(data.get("results", []))
            if not score_page_flag:
                total = data.get("totalCount", 0)
                page_list = []
                if total > 100:
                    page_count = math.ceil(total / 100)
                    page_list = list(range(2, page_count + 1))
            else:
                page_list = response.meta.get("page_list", [])
            if page_list:
                page = page_list.pop(0)
                score_data = {"offlineScoreType": 2, "pageNo": page, "pageSize": 100}
                yield Request(url=self.score_url, callback=self.score_parse, method="POST", headers=header,
                              body=json.dumps(score_data), dont_filter=True, cb_kwargs=kwargs, errback=self.err_parse,
                              meta={"score_page_flag": True, "score_list": score_list, "header": header,
                                    "page_list": page_list})
            else:
                score_data = score_list
                result = self.result_item_assembler(response)
                result['result_data'] = {'score_data': score_data}
                yield result
                new_card_number = kwargs.get("new_card_number", "")
                yield Request(url=self.unbind_url, callback=self.unbind_parse, method="POST", headers=header, errback=self.err_parse,
                              body=json.dumps({"cardNumber": new_card_number}), dont_filter=True, cb_kwargs=kwargs)
        except Exception:
            self.logger.error(f"解析成绩信息时出错：{traceback.format_exc()}")

    def err_parse(self, failure):
        self.logger.warning(f"请求失败：{failure.request.url},错误原因:{traceback.format_exc()}")
